iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0

  今天介紹的State Pattern與昨天的Strategy Pattern非常的相似,不過它們之間到底有沒有甚麼差別呢?現在就帶你一起來了解!


問題情境與解析

  通常程式如果碰到「因狀態不同而需要有不同的邏輯行為或是處理步驟」,第一個直覺就會想到if-else 或是 switch-case,不過開始添加物件新的狀態與其行為時,很可能此類別的方法就會有可怕的條件式,像這樣的程式很難去維護,因為對於邏輯轉換的修改都可能需要更改每一個方法中的狀態條件,隨著程式的發展,問題往往只會越來越大,所有狀態的條件式也可能變得臃腫不堪。

  碰到這種問題,透過狀態模式,我們會將物件所有的狀態拉出來創一個新的類別,並包含該狀態所有的行為,而物件本身只需要有狀態的屬性來儲存其狀態,好讓它可以呼叫該狀態的行為模式。

  再舉個例子來說,就像手機可以簡單分成一般模式、震動模式及勿擾模式(不同的狀態類別),在一般模式下,有通知會正常響鈴並顯示資訊在螢幕上;震動模式的話不會響鈴但是會讓手機震動;勿擾模式就不會有任何動作了。以上示例了一件事情在三個狀態下做了不一樣的行為,相信大家對於狀態模式又更加熟悉了!

Class Diagram

https://ithelp.ithome.com.tw/upload/images/20210930/20140743ErMfDVNY4o.png

Skeleton Code

class Context {
    private State state;
    
    public Context(State initialState) {
        // initial state
        this.state = initialState;
        state.setContext(this);
    }

    public void setState(State state) {
        this.state = state;
    }

    public Type request() {
        state.handle();
    }
}

interface State {
    public Type handle();
}

class ConcreteState1 implements State {	
    private Context context;

    public void setContext(Context context) {	   
        this.context = context;
    }  

    public Type handle() {	   
        // A state may issue state transition in context
        context.setState(new ConcreteState2);

        // other operation
    }
}

class ConcreteState2 implements State {	        
    private Context context;

    public void setContext(Context context) {	   
        this.context = context;
    }  

    public Type handle() {	   
        // other operation
    }
}

  看到這邊,是不是覺得與上一篇的Strategy Pattern整體的結構非常相似,但它們有個關鍵的區分方式,就是在狀態模式中,特定的狀態可能會與其他狀態有所關聯,來達到物件的狀態轉換;反之,策略之間幾乎不瞭解彼此,並且獨立的存在。


除此之外,也歡迎大家走走逛逛關於我們團隊夥伴的文章

lu23770127 - SASS 基礎初學三十天

10u1 - 糟了!是世界奇觀!

juck30808 - Python - 數位行銷分析與 Youtube API 教學

SiQing47 - 前端?後端?你早晚都要全端的,何不從現在開始?


上一篇
IT鐵人DAY 16-Strategy 策略模式
下一篇
IT鐵人DAY 18-Adapter 適配器模式
系列文
淺談物件導向與Design Pattern介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言